package io.gitee.zhangbinhub.admin.oauth.component

import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.oauth.constant.OauthConstant
import io.gitee.zhangbinhub.admin.oauth.entity.User
import io.gitee.zhangbinhub.admin.oauth.service.ModuleFuncService
import io.gitee.zhangbinhub.admin.oauth.service.RuntimeConfigService
import io.gitee.zhangbinhub.admin.oauth.service.UserService
import org.noear.solon.annotation.Component

@Component
class AuthUserService(
    private val logAdapter: LogAdapter,
    private val userService: UserService,
    private val moduleFuncService: ModuleFuncService,
    private val runtimeConfigService: RuntimeConfigService
) {
    /**
     * 根据 username 获取用户信息
     *
     * @param username 用户名
     * @return 用户对象
     * @throws SaOAuth2Exception 找不到用户信息异常
     */
    @Throws(SaOAuth2Exception::class)
    fun loadUserByUsername(username: String): User =
        userService.getUserInfoByLoginNo(username) ?: throw SaOAuth2Exception("无此用户：$username")

    /**
     * 记录用户密码错误次数
     */
    @Throws(SaOAuth2Exception::class)
    fun storePasswordErrorTime(username: String) = userService.storePasswordErrorTime(username).let {
        runtimeConfigService.findByName(OauthConstant.passwordErrorTime)?.let { runtimeConfig ->
            if (runtimeConfig.enabled && !CommonTools.isNullStr(runtimeConfig.value)) {
                runtimeConfig.value!!.toInt().let { maxPasswordErrorTime ->
                    if (maxPasswordErrorTime in 1..it) {
                        userService.getUserInfoByLoginNo(username)?.apply {
                            this.enabled = false
                            userService.doSaveUser(this)
                        }
                        logAdapter.error("错误次数达${maxPasswordErrorTime}次，账号已禁用，请联系系统管理员！")
                        throw SaOAuth2Exception("错误次数达${maxPasswordErrorTime}次，账号已禁用，请联系系统管理员！")
                    }
                }
            }
        }
    }

    /**
     * 清除用户密码错误次数
     */
    fun clearPasswordErrorTime(username: String) = userService.clearPasswordErrorTime(username)

    fun getPermissionList(loginId: Any): MutableList<String> =
        userService.getUserInfoByLoginNo(loginId.toString())?.let { user ->
            mutableListOf<String>().apply {
                moduleFuncService.getModuleFuncList(user.id).forEach { module ->
                    this.add(module.code) //模块功能编码
                }
                user.roleSet.forEach { role ->
                    this.add("${RoleCode.prefix}${role.code}") //角色编码
                }
            }
        } ?: mutableListOf()

    fun getRoleList(loginId: Any): MutableList<String> =
        userService.getUserInfoByLoginNo(loginId.toString())?.let { user ->
            mutableListOf<String>().apply {
                user.roleSet.forEach { role ->
                    this.add(role.code) //角色编码
                }
            }
        } ?: mutableListOf()
}
